package net.p2pcdn.user.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qc.bean.result.Paging;
import net.p2pcdn.core.order.domain.PayType;
import net.p2pcdn.core.order.domain.PlatformEnum;
import net.p2pcdn.core.order.service.OrderService;
import net.p2pcdn.user.domain.User;
import net.p2pcdn.user.domain.UserAccount;
import net.p2pcdn.user.domain.UserAccountChangeRecord;
import net.p2pcdn.user.repository.UserAccountChangeRecordRepository;
import net.p2pcdn.user.repository.UserAccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zx
 */
@Service
public class UserAccountService {
    @Autowired
    private UserService userService;
    @Resource
    private UserAccountRepository userAccountRepository;
    @Resource
    private UserAccountChangeRecordRepository userAccountChangeRecordRepository;
    @Autowired
    private OrderService orderService;

    public UserAccount getUserAccount(int userId) {
        User user = userService.getById(userId);
        UserAccount userAccount = userAccountRepository.findByUserId(userId);
        if (userAccount == null) {
            userAccount = new UserAccount(user.getId(), new BigDecimal("0"));
            userAccountRepository.insert(userAccount);
        }
        return userAccount;
    }

    public void chargeBalance(int creator, int userId, BigDecimal delta, UserAccountChangeRecord.BizType bizType, String remark) {
        UserAccount userAccount = this.getUserAccount(userId);
        userAccount.setBalance(userAccount.getBalance().add(delta));
        userAccount.setUpdateTime(new Date());
        int result = this.userAccountRepository.updateByPrimaryKey(userAccount);
        if (result == 0) {
            throw new RuntimeException("账户充值失败，请重新尝试");
        }
        UserAccountChangeRecord changeRecord = new UserAccountChangeRecord(userAccount.getId(), delta,
                delta.compareTo(new BigDecimal("0")) < 0, bizType.getValue(), userAccount.getBalance());
        changeRecord.setRemark(remark);
        userAccountChangeRecordRepository.insert(changeRecord);
        //线下付款也生产一个支付订单
        if(UserAccountChangeRecord.BizType.OFF_LINE_PAY == bizType){
            orderService.addChargeOrder(creator,userId,delta, PayType.OFFLINE, PlatformEnum.UNKNOWN);
        }
    }

    public void expense(int userId, BigDecimal delta, UserAccountChangeRecord.BizType bizType, String remark,Integer orderId) {
        UserAccount userAccount = this.getUserAccount(userId);
        if (userAccount.getBalance().compareTo(delta) < 0) {
            throw new RuntimeException("账户余额不足");
        }
        userAccount.setBalance(userAccount.getBalance().subtract(delta));
        userAccount.setUpdateTime(new Date());
        int result = this.userAccountRepository.updateByPrimaryKey(userAccount);
        if (result == 0) {
            throw new RuntimeException("账户充值失败，请重新尝试");
        }
        UserAccountChangeRecord changeRecord = new UserAccountChangeRecord(userAccount.getId(), delta,
                true, bizType.getValue(), userAccount.getBalance());
        changeRecord.setRemark(remark);
        changeRecord.setOrderId(orderId);
        userAccountChangeRecordRepository.insert(changeRecord);
    }

    public Paging<UserAccountChangeRecord> queryChangeRecords(String email, Integer userId, Boolean negative,
                                                              UserAccountChangeRecord.BizType bizType, int page, int size) {
        PageHelper.startPage(page, size);
        Map<String, Object> params = new HashMap<>(8);
        params.put("userId", userId);
        params.put("email", email);
        params.put("negative", negative);
        params.put("bizType", bizType == null ? null : bizType.getValue());
        List<UserAccountChangeRecord> recordList = userAccountChangeRecordRepository.query(params);
        PageInfo<UserAccountChangeRecord> pageInfo = new PageInfo<>(recordList);
        return new Paging<>((int) pageInfo.getTotal(), recordList);
    }

    public UserAccount findByUsername(String username) {
        User user = userService.findByUsername(username);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        return this.getUserAccount(user.getId());
    }
}
